<?php

namespace App\Library\Service;

use App\Library\Logic\AfterSaleLogic;
use App\Library\Logic\AuctionOrderLogic;
use App\Library\Requests\AfterSale\AfterSaleAuctionApply;
use App\Library\Requests\Base\BaseDeliveryRequest;
use App\Library\Requests\Base\SerialNumberRequest;
use App\Library\YsdLib;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Http\JsonResponse;
use Yansongda\Pay\Pay;

class AfterSaleService extends BaseService
{
    /**
     * logic
     * @return AfterSaleLogic
     */
    protected function logic(): AfterSaleLogic
    {
        if (empty($this->logic)) $this->logic = new AfterSaleLogic;
        return $this->logic;
    }

    public function auctionApply(AfterSaleAuctionApply $request): JsonResponse
    {
        $order = AuctionOrderLogic::afterSaleCheck($request->serialNumber);
        if (is_null($order)) return fail(433);
        else if (!is_null($order->afterSale) && $order->afterSale->status === 0) return failMessage('退款正在处理中');
        $array = handleRequest($request);
        unset($array['serialNumber']);
        $this->logic()->insertForModel(array_merge($array, [
            'orderStatus' => $order->status,
            'userId' => USERID,
            'sellerId' => $order->seller_id,
            'payPrice' => $order->pay_price,
            'objectType' => $order->getTable(),
            'objectId' => $order->id,
        ]));
        $order->status_after_sale = 1;
        $order->save();
        return success();
    }

    /**
     * 售后详情
     * @param SerialNumberRequest $request
     * @return JsonResponse
     */
    public function auctionDetail(SerialNumberRequest $request): JsonResponse
    {
        $item = $this->logic()->findBySerialNumber($request);
        if (is_null($item) || $item->object_type !== 'auction_order') return fail(433);
        $item->auctionOrder->auctionInfo;
        $item->auctionOrder->auctionInfo->address;
        $item->logistics;
        return success($item);
    }

    /**
     * auctionCancel
     * @param SerialNumberRequest $request
     * @return JsonResponse
     */
    public function auctionCancel(SerialNumberRequest $request): JsonResponse
    {
        $afterSale = AfterSaleLogic::findBySerialNumber($request);
        if (is_null($afterSale) || $afterSale->user_id !== USERID) return fail(433);
        else if (in_array($afterSale->status, [1, 2])) return failMessage('当前状态不可取消');
        $afterSale->status = 3;
        $afterSale->save();
        $afterSale->auctionOrder->status_after_sale = 4;
        $afterSale->auctionOrder->save();
        return success();
    }

    /**
     *
     * @param BaseDeliveryRequest $request
     *
     * @return JsonResponse
     * @throws GuzzleException
     */
    public function userDelivery(BaseDeliveryRequest $request): JsonResponse
    {
        $afterSale = $this->logic()->findBySerialNumber($request);
        if (is_null($afterSale)) return fail(433);
        else if ($afterSale->object_type !== 'auction_order') return fail(433);
        else if ($afterSale->status !== 1) return fail(618);
        $afterSale->status_deliver = 1;
        $afterSale->deliver_at = now();
        $afterSale->save();
        LogisticsService::delivery($afterSale->id, $request->expressNo, 0, 1);
        return success();
    }

    /**
     *
     * @param SerialNumberRequest $request
     * @return JsonResponse
     * @throws GuzzleException
     */
    public function logistics(SerialNumberRequest $request): JsonResponse
    {
        $afterSale = $this->logic()->findBySerialNumber($request);
        if (is_null($afterSale)) return fail(433);
        else if ($afterSale->status_deliver !== 1) return fail(615);
        else if ($afterSale->status === 3) return fail(434);
        if ($afterSale->logistics->status_sign === 1) return success($afterSale->logistics->info);
        else return success(LogisticsService::logistics($afterSale));
    }

    /**
     *
     * Author: zlf
     * Created at 2024/11/28 17:40
     * @param $request
     */
    public function afterSaleList($request): JsonResponse
    {
        $sale = AfterSaleLogic::query()
            ->select(
                'after_sale.*',
                'b.user_name  as buy_name',
                'b.user_mobile  as buy_mobile',
                'b.user_nickname  as buy_nickname',
                'c.user_name  as sell_name',
                'c.user_mobile  as sell_mobile',
                'c.user_nickname  as sell_nickname',
                'd.title as product_name',
                'd.file_id as product_img_id'
            )
            ->leftJoin('shop_user as b', 'b.user_id', '=', 'after_sale.user_id')
            ->leftJoin('shop_user as c', 'b.user_id', '=', 'after_sale.seller_id')
            ->leftJoin('auction as d', 'd.id', '=', 'after_sale.object_id')
            ->where([
                'seller_id' => USERID,
                'object_type' => 'auction_order'
            ])->whereIn('after_sale.status', [0, 1, 2])->orderBy('created_at','desc');
        return success(paginate(helpBuilder($sale, $request)->paginate($request->post('limit'))));
    }

    public function refund($request): JsonResponse
    {
        $afterSale = $this->logic()->findBySerialNumber($request);
        if (is_null($afterSale)) return failMessage('无售后订单信息');
        if (USERID !== $afterSale->seller_id) return failMessage('您无权操作！');
        else if (!in_array($afterSale->status, [0, 1])) return failMessage('未同意,不能退款！');
        else if (is_null($afterSale->paymentRelated)) return failMessage('无订单支付信息');
        else if (is_null($afterSale->payment)) return failMessage('无支付信息');
        $afterSale->reply = $request->reply ?? '';
        if ((int)$request->status === 2) {//拒绝
            $afterSale->status = 2;
            $afterSale->refuse_at = now();
            $afterSale->auctionOrder->status_after_sale = 3;
            $afterSale->save();
            $afterSale->auctionOrder->save();
            return success();
        }
        if ((float)$request->price < (float)$afterSale->pay_price) {//指定金额
            $afterSale->refund_type_id = 1;
            $afterSale->refund_price = $request->price;
        } else if ((float)$request->price == (float)$afterSale->pay_price) {//全退
            $afterSale->refund_price = $afterSale->pay_price;
        } elseif ((float)$request->price > (float)$afterSale->pay_price) {
            return failMessage('退款金额不能大于支付金额');
        }
        $afterSale->status = 1;
        $afterSale->agree_at = now();
        if (!is_null($afterSale->auctionOrder)) {
            $afterSale->auctionOrder->status_after_sale = 2;
            $afterSale->auctionOrder->status = 4;
            $afterSale->auctionOrder->save();
        }
        $result = Pay::wechat(YsdLib::config())->refund([
            'transaction_id' => $afterSale->payment->out_trade_no,
            'out_trade_no' => $afterSale->paymentRelated->serial_number,
            'out_refund_no' => $afterSale->serial_number,
            'reason' => '退款',
            'notify_url' => config('app.url') . 'wechat/afterSaleRefund',
            'amount' => [
                'refund' => prod() ? (int)bcmul($afterSale->refund_price, 100) : 1,
                'total' => prod() ? (int)bcmul($afterSale->refund_price, 100) : 1,
                'currency' => 'CNY',
            ],
        ]);
        $afterSale->remit_at = now();
        $afterSale->status_arrival = 99;
        $afterSale->save();
        return success();
    }
}
